iT邦幫忙

2022 iThome 鐵人賽

DAY 18
0

今天來繼續我們的困難閉包。

尾隨閉包

尾隨閉包就是當你的閉包做為函數的參數時,可以用尾隨閉包來縮短程式碼的表達式。

func someFunctionThatTakesAClosure(closure: () -> Void) {
    // 函数部分
}

// 以下是不使用尾隨閉包的函數調用
someFunctionThatTakesAClosure(closure: {
    //閉包部分
})

// 以下是有使用尾隨閉包的版本
someFunctionThatTakesAClosure() {
    // 閉包部分
}

而依照前面排序的例子。 sorted(by:) 的方法可以寫成下面的方式。

reversedNames = names.sorted() { $0 > $1 }

而如果閉包表達式是函數的唯一參數可以把 () 省略掉

reversedNames = names.sorted { $0 > $1 }

當閉包長度非常長,無法在一行中寫完時,尾隨閉包就很好使用。
來看官方的例子。

let digitNames = [
    0: "Zero", 1: "One", 2: "Two",   3: "Three", 4: "Four",
    5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
]
let numbers = [16, 58, 510]

官方的例子要用高階函數 map(_:) 來做示範。
然後要做到 Int 轉成 String,所以先做上面的設定。

let strings = numbers.map {
    (number) -> String in
    var number = number
    var output = ""
    repeat {
        output = digitNames[number % 10]! + output
        number /= 10
    } while number > 0
    return output
}
// strings 會被推斷成 [String]
// 裡面得值獲得到轉換 ["OneSix", "FiveEight", "FiveOneZero"]

接下來當 map 遍歷 numbers 裡面的數值,閉包的 number 會獲得數值,並開始 repeat-while 方法,先檢查數值有沒有大於 0 如果沒有就在裡面循環。
那中間 repeat 裡面在寫什麼呢?

output = digitNames[number % 10]! + output
number /= 10

第一個就是 output 會是 number 求餘 對上的 字典返回 String , 然後 number 會在 除10 繼續循環。
那第一個數值 16 就會先求餘拿到 6 再轉換成Six
之後 number 除10 會拿到 1 再轉換成 One 依此類推。

如果一個函數要使用多個閉包,可以省略第一個尾隨閉包函數的標籤,並未其他尾隨閉包添加標籤。

func loadPicture(from server: Server, completion:(Picture) -> Void,
		onFailure: () -> Void) {
	if let picture = download("photo.jpg", from: server){
		completion(picture)
	}else{
		onFailure()
	}
}

調用的時候長這樣。

loadPicture(from: someServer){	picture in
	someView.currentPicture = picture
} onFailure: {
	print("Couldn't download the next picture.")
}

上面是第一個閉包是完成處理程序,成功下載並加載圖片。另一個則是錯誤處理。

OK,今天就先到這裡,明天再繼續。


上一篇
30天的 iOS 修仙道路 (17)
下一篇
30天的 iOS 修仙道路 (19)
系列文
30天的 iOS 修仙道路 站穩腳步基礎篇30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言